package com.wingscode.modules.app.controller;


import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.wingscode.common.utils.AesCbcUtil;
import com.wingscode.common.utils.R;
import com.wingscode.common.validator.ValidatorUtils;
import com.wingscode.modules.app.form.*;
import com.wingscode.modules.app.utils.JwtUtils;
import com.wingscode.modules.app.utils.SmsUtil;
import com.wingscode.modules.app.utils.WXUtil;
import com.wingscode.modules.common.entity.*;
import com.wingscode.modules.common.service.*;
import com.wingscode.modules.sys.controller.AbstractController;

import com.wingscode.modules.sys.entity.VipLevelEntity;
import com.wingscode.modules.sys.service.VipLevelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.*;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * APP登录授权
 *
 * @author yan
 */
@RestController
@RequestMapping("/app/common")
@Api("APP通用接口")
public class AppCommonController extends AbstractController {
    @Autowired
    private AdvertisementService advertisementService;
    @Autowired
    private UserService userService;
    @Autowired
    private SecurityCodeService securityCodeService;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private AgentService agentService;
    @Autowired
    private VipLevelService vipLevelService;
    @Autowired
    private WxUserService wxUserService;
    @Autowired
    private ServiceUsageRecordService serviceUsageRecordService;

//    /**
//     * 登录
//     */
//    @PostMapping("login")
//    @ApiOperation("登录")
//    public R login(@RequestBody LoginForm form) {
//        //表单校验
//        ValidatorUtils.validateEntity(form);
//
//        //用户登录
//        UserEntity userEntity = userService.login(form);
//        //生成token
//        String token = jwtUtils.generateToken(userEntity.getId());
//
//        UserInfoForm userInfoForm = new UserInfoForm().getUserInfo(userEntity);
//        userInfoForm.setToken(token);
//        return R.ok(200, userInfoForm);
//    }

    /**
     * 微信授权登录
     */
    @PostMapping("loginByCode")
    @ApiOperation("微信授权登录")
    public R login(@RequestParam String code) throws IOException {
        String openId = "", sessionKey = "", unionid = "";
        JSONObject jsonObject = new WXUtil().getOpenId(code);
        if (jsonObject != null) {
            openId = (String)jsonObject.get("openid");
            sessionKey = (String)jsonObject.get("session_key");
            unionid = (String)jsonObject.get("unionid");
        }

        //用户登录
        UserEntity userEntity = userService.loginByCode(openId);
        if (userEntity == null || (userEntity != null && userEntity.getId() == null)) {
            userEntity.setCreateTime(new Date());
            userEntity.setUpdateTime(new Date());
            userEntity.setRole(99);
            userEntity.setIsOfferPrice(0);
            userEntity.setStatus(1);
            userService.save(userEntity);

            WxUserEntity wxUser = new WxUserEntity();
            wxUser.setUserId(userEntity.getId());
            wxUser.setOpenId(openId);
            wxUser.setSessionKey(sessionKey);

            wxUserService.save(wxUser);
        }

        userEntity.setOpenId(openId);
        userEntity.setSessionKey(sessionKey);

        //生成token
        String token = jwtUtils.generateToken(userEntity.getId());
        UserInfoForm userInfoForm = new UserInfoForm().getUserInfo(userEntity);
        userInfoForm.setToken(token);
        return R.ok(200, userInfoForm);
    }

    @PostMapping("saveWxUser")
    @ApiOperation("保存微信用户信息")
    public R saveWxUser(@RequestBody MpAuthForm form) {
        UserInfoForm userInfoForm = null;
        if (form.getEncryptedData().isEmpty())
            return R.error("encryptedDate为空");
        if (form.getSessionKey().isEmpty())
            return R.error("sessionKey为空");
        if (form.getIv().isEmpty())
            return R.error("iv为空");
        if (form.getOpenId().isEmpty())
            return R.error("openId为空");

        // 解析相应内容（转换成json对象）
        Gson gson = new Gson();
        // 对encryptedData加密数据进行AES解密
        String encryptedData = form.getEncryptedData().replaceAll(" ", "+");
        String iv = form.getIv().replaceAll(" ", "+");
        String sessionKey = form.getSessionKey().replaceAll(" ", "+");

        try {
            String result = AesCbcUtil.decrypt(encryptedData, sessionKey, iv, "UTF-8");
            if (null != result && result.length() > 0) {
                JsonObject userInfoJSON = gson.fromJson(result, JsonObject.class);
                String phone = userInfoJSON.get("phoneNumber").toString().replaceAll("\"", "");

                // 查询当前手机号是否已存在
                UserEntity entity = userService.queryByMobile(phone);
                WxUserEntity wxUser = wxUserService.getOne(new QueryWrapper<WxUserEntity>().eq("open_id", form.getOpenId()));
                if (wxUser != null)
                {
                    if (entity == null) {
                        // 手机号不存在，更新openId对应userId的用户信息
                        entity = userService.getById(wxUser.getUserId());
                        entity.setMobile(phone);
                        entity.setUsername("用户" + phone.substring(7));
                        entity.setUpdateTime(new Date());

                        userService.updateById(entity);
                    } else {
                        // 手机号存在，更新openId对应的userId
                        wxUser.setUserId(entity.getId());

                        wxUserService.updateById(wxUser);
                    }

                    entity.setOpenId(form.getOpenId());
                    entity.setSessionKey(form.getSessionKey());
                }

                // 获得企业认证状态
                if (entity.getAgentId() != null) {
                    AgentEntity agentEntity = agentService.getById(entity.getAgentId());
                    if (agentEntity != null) {
                        entity.setAgentState(agentEntity.getState());
                        entity.setAgentName(agentEntity.getCompany());
                        entity.setLevel(agentEntity.getLevel());
                        entity.setIsOfferPrice(agentEntity.getIsOfferPrice());
                        // 会员名称
                        if (agentEntity.getLevel() != null) {
                            VipLevelEntity vipLevel = vipLevelService.getById(agentEntity.getLevel());
                            if (vipLevel != null)
                                entity.setLevelName(vipLevel.getName());
                        }
                    }
                }

                //生成token
                String token = jwtUtils.generateToken(entity.getId());
                userInfoForm = new UserInfoForm().getUserInfo(entity);
                userInfoForm.setToken(token);

            } else {
                return R.error("手机号解密失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return R.ok(200, userInfoForm);
    }

    @PostMapping("register")
    @ApiOperation("注册/登录")
    public R register(@RequestBody RegisterByCodeForm form) {
        //表单校验
        ValidatorUtils.validateEntity(form);
        if (getSecurityCodeEntity(form.getBizId()).getCode().equals(form.getSecurityCode())) {
            // 检查当前手机号是否存在
            UserEntity user = userService.queryByMobile(form.getMobile());
            if (user == null) {
                // 当前手机号不存在，直接注册
                user = new UserEntity();
                user.setMobile(form.getMobile());
                user.setUsername("用户" + form.getMobile().substring(7));
                user.setCreateTime(new Date());
                user.setUpdateTime(new Date());
                user.setRole(99);
                user.setIsOfferPrice(0);
                user.setStatus(1);
                userService.save(user);
            }

            // 获得企业认证状态
            if (user.getAgentId() != null) {
                AgentEntity agentEntity = agentService.getById(user.getAgentId());
                if (agentEntity != null) {
                    user.setAgentState(agentEntity.getState());
                    user.setAgentName(agentEntity.getCompany());
                    user.setLevel(agentEntity.getLevel());
                    user.setIsOfferPrice(agentEntity.getIsOfferPrice());
                }
            }

            UserInfoForm userInfoForm = new UserInfoForm().getUserInfo(user);
            String token = jwtUtils.generateToken(user.getId());
            userInfoForm.setToken(token);
            return R.ok(200, userInfoForm);
        } else {
            return R.error("验证码错误");
        }
    }

    @PostMapping("saveCompany")
    @ApiOperation("保存企业信息")
    public R saveCompany(@RequestBody AgentForm agentForm) {
        //表单校验
        ValidatorUtils.validateEntity(agentForm);
        // 检查当前企业名称、证件编号是否已存在
        List<AgentEntity> list = agentService.list(
                new QueryWrapper<AgentEntity>()
                        .eq("company", agentForm.getCompany())
                        .or()
                        .eq("certificate_num", agentForm.getCertificateNum())
        );

        if (list != null && list.size() > 0 && agentForm.getAgentId() == null) {
            return R.error("当前企业名称/证件编号已经被注册，请直接登录或添加员工账户");
        } else {
            // 保存企业信息
            AgentEntity agent = null;
            if (agentForm.getAgentId() != null)
                agent = agentService.getById(agentForm.getAgentId());
            if (agent == null)
                agent = new AgentEntity();

            agent.setCompany(agentForm.getCompany());
            agent.setLogo(agentForm.getLogo());
            agent.setImgUrls(agentForm.getImgUrls());
            agent.setCertificateNum(agentForm.getCertificateNum());
            agent.setArea(agentForm.getArea());
            agent.setAreaPId(agentForm.getAreaPId());
            agent.setAddress(agentForm.getAddress());
            agent.setCertificateImg(agentForm.getCertificateImg());

            if (agentForm.getAgentId() != null) {
                if (agent.getState() == 2)
                    agent.setState(0);
                agent.setUpdateTime(new Date());

                agentService.updateById(agent);
            } else {
                agent.setCreateTime(new Date());
                agent.setUpdateTime(new Date());
                agent.setState(0);
                agent.setType(1);
                agent.setResource(0);
                agent.setLevel(1);
                agent.setState(0);
                agent.setIsOfferPrice(0);
                agent.setIsStart(1);

                // 获得注册企业发布次数
                VipLevelEntity vipLevelEntity = vipLevelService.getById(1);
                if (vipLevelEntity != null) {
                    agent.setQualNum(vipLevelEntity.getQualNum());
                    agent.setPersonnelNum(vipLevelEntity.getPersonnelNum());

                    // 保存增值服务初始数据
                    Integer qualNum = vipLevelEntity.getQualNum() != null ? vipLevelEntity.getQualNum() : 0;
                    Integer personnelNum = vipLevelEntity.getPersonnelNum() != null ? vipLevelEntity.getPersonnelNum() : 0;
                    Integer num = qualNum + personnelNum;
                    if (num > 0) {
                        ServiceUsageRecordEntity recordEntity = new ServiceUsageRecordEntity();
                        recordEntity.setAgentId(agent.getId());
                        recordEntity.setTitle("初始注册获得");
                        recordEntity.setNum(vipLevelEntity.getQualNum() + vipLevelEntity.getPersonnelNum());
                        recordEntity.setCreateTime(new Date());
                        recordEntity.setSource(0);
                        recordEntity.setType(1);
                        recordEntity.setUserId(agentForm.getUserId());

                        serviceUsageRecordService.save(recordEntity);
                    }
                }

                agentService.save(agent);
            }

            // 将企业id与用户信息绑定
            UserEntity userEntity = userService.getById(agentForm.getUserId());
            if (userEntity != null) {
                userEntity.setAgentId(agent.getId());
                userEntity.setUpdateTime(new Date());

                userService.updateById(userEntity);

                userEntity.setAgentState(agent.getState());
                userEntity.setAgentName(agent.getCompany());
                userEntity.setLevel(agent.getLevel());
            }
            UserInfoForm userInfoForm = new UserInfoForm().getUserInfo(userEntity);

            return R.ok(200, userInfoForm);
        }
    }

    /**
     * 获取验证码
     */
    @PostMapping("getSecurityCode")
    @ApiOperation("获取验证码")
    public R getSecurityCode(@RequestParam String phone, @RequestParam Integer isLogin) throws ClientException {
        if (phone.isEmpty())
            return R.error("phone为空");
        if (isLogin == null)
            return R.error("isLogin为空");

        if (isLogin == 1) {
            // 检查当前手机号是否已注册
            UserEntity userEntity = userService.queryByMobile(phone);
            if (userEntity != null && userEntity.getAgentId() != null)
                return R.error("当前手机号已经加入其他公司，无法重复加入");
        }

        String code = (int) ((Math.random() * 9 + 1) * 100000) + "";
        SecurityCodeFrom securityCodeFrom = new SmsUtil().getSecurityCode(phone, code);
        SecurityCodeEntity securityCodeEntity = new SecurityCodeEntity();
        securityCodeEntity.setGmtCreate(new Date());
        securityCodeEntity.setGmtModified(new Date());
        securityCodeEntity.setPhone(phone);
        securityCodeEntity.setStatus(1);
        securityCodeEntity.setBizid(securityCodeFrom.getBizId());
        securityCodeEntity.setCode(code);
        securityCodeService.save(securityCodeEntity);
        
        return R.ok(200, securityCodeFrom);
    }

    @GetMapping("userInfo")
    @ApiOperation("获取用户信息")
    public R userInfo(@RequestParam Integer userId) {
        UserEntity user = userService.getById(userId);
        if (user != null) {
            AgentEntity agent = agentService.getById(user.getAgentId());
            if (agent != null) {
                user.setAgentName(agent.getCompany());
                user.setAgentState(agent.getState());
                user.setIsOfferPrice(agent.getIsOfferPrice());
                VipLevelEntity vipLevel = vipLevelService.getById(agent.getLevel());
                if (vipLevel != null)
                    user.setLevelName(vipLevel.getName());
            }
        }
        UserInfoForm userInfoForm = new UserInfoForm().getUserInfo(user);
        
        return R.ok(200, userInfoForm);
    }

//    @PostMapping("resetPwd")
//    @ApiOperation("重置密码")
//    public R resetPwd(@RequestBody RegisterForm form) {
//        //表单校验
//        ValidatorUtils.validateEntity(form);
//        if (getSecurityCodeEntity(form.getBizId()).getCode().equals(form.getSecurityCode())) {
//            UserEntity user = userService.queryByMobile(form.getMobile());
//            user.setPassword(DigestUtils.sha256Hex(form.getPassword()));
//            user.setUpdateTime(new Date());
//            userService.updateById(user);
//            return R.ok(200, "");
//        } else {
//            return R.error("验证码错误");
//        }
//    }

    /**
     * 获取广告
     */
    @GetMapping("/getBannerList")
    @ApiOperation("轮播图")
    public R getBannerList() {
        List<AdvertisementEntity> list = advertisementService.list(
                new QueryWrapper<AdvertisementEntity>()
                        .eq("status", 1)
                        .eq("type", 2)
                        .eq("dic_id", 151)
                        .orderByAsc("sort")
        );

        return R.ok(200, list);
    }

    private SecurityCodeEntity getSecurityCodeEntity(String bizId) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.MINUTE, 10);
        Date d1 = c.getTime();
        return securityCodeService.getOne(new QueryWrapper<SecurityCodeEntity>().eq("bizid", bizId).le("gmt_create", d1));
//        SecurityCodeEntity securityCodeEntity = securityCodeService.getOne(new QueryWrapper<SecurityCodeEntity>().eq("bizid", bizId));
//        return securityCodeEntity;
    }

}
